package hash

import (
	"crypto/aes"
	"crypto/cipher"
	"ecms/config"
	"ecms/models"
	"encoding/base64"
	"encoding/json"
	"time"
)

type AdminAccessTokenInfo struct {
	Model     models.AdminMember `json:"model"`
	ExpiresAt int64              `json:"expires_at"`
}

func EncryptAdminAccessToken(model models.AdminMember) (string, error) {
	tokenInfo := AdminAccessTokenInfo{
		Model:     model,
		ExpiresAt: time.Now().Local().Unix() + config.Hash().AdminAccessTokenExpiresSeconds,
	}
	plainText, err := json.Marshal(tokenInfo)
	if err != nil {
		return "", err
	}
	block, err := aes.NewCipher([]byte(config.Hash().AdminAccessTokenSalt))
	if err != nil {
		return "", err
	}
	plainBytes := pKCS5Padding(plainText, aes.BlockSize)
	buf := make([]byte, len(plainBytes))
	mode := cipher.NewCBCEncrypter(block, []byte(config.Hash().AdminAccessTokenSalt))
	mode.CryptBlocks(buf, plainBytes)
	return base64.StdEncoding.EncodeToString(buf), nil
}

func DecryptAdminAccessToken(token string) (*AdminAccessTokenInfo, error) {
	decodeString, err := base64.StdEncoding.DecodeString(token)
	if err != nil {
		return nil, err
	}
	token = string(decodeString)
	block, err := aes.NewCipher([]byte(config.Hash().AdminAccessTokenSalt))
	if err != nil {
		return nil, err
	}
	buf := make([]byte, len(token))
	mode := cipher.NewCBCDecrypter(block, []byte(config.Hash().AdminAccessTokenSalt))
	mode.CryptBlocks(buf, []byte(token))
	buf = pKCS5UnPadding(buf)
	tokenInfo := AdminAccessTokenInfo{}
	if err = json.Unmarshal(buf, &tokenInfo); err != nil {
		return nil, err
	}
	return &tokenInfo, nil
}
